package com.wzh.navcode.websocket;

import cn.hutool.json.JSONUtil;
import com.wzh.navcode.domain.vo.UserLoginVO;
import com.wzh.navcode.domain.vo.WebsocketMsgVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: wangzh
 * @Version: 1.0
 * @Description:
 */
@Slf4j
@ServerEndpoint("/websocket/{uuid}")
@Component
public class WebSocketServer {

    /**
     * 存储 UUID 和 WebSocket Session 的映射关系
     */
    private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();

    /**
     * 存储 微信用户openId 和 UUID 的映射关系
     */
    private static ConcurrentHashMap<String, String> wxUserMap = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("uuid") String uuid) {
        sessionMap.put(uuid, session);
        log.info("新的WebSocket连接：{}", uuid);
    }

    /**
     * 当微信用户扫码时，记录openId和uuid的关系
     * @param openId 微信用户openId
     * @param uuid uuid
     */
    public static void bindWxUser(String openId, String uuid) {
        wxUserMap.put(openId, uuid);
        // 可以通知前端已扫码
        WebsocketMsgVO vo = WebsocketMsgVO.builder().type("scan").status("success").build();
        sendMessage(uuid, JSONUtil.toJsonStr(vo));
    }

    /**
     * 当用户点击授权时，通过openId找到对应的uuid，再通知对应的前端用户
     * @param openId 微信用户openId
     * @param user 用户信息
     */
    public static void notifyAuthSuccess(String openId, UserLoginVO user) {
        String uuid = wxUserMap.get(openId);
        if (uuid != null) {
            if (uuid.startsWith("qrscene_")) {
                // 如果是扫码关注进来的uuid会被带上前缀qrscene_，需要去掉
                uuid = uuid.replaceFirst("^qrscene_", "");
            }
            WebsocketMsgVO vo = WebsocketMsgVO.builder().type("auth").status("success").data(user).build();
            sendMessage(uuid, JSONUtil.toJsonStr(vo));
            // 清理映射关系
            wxUserMap.remove(openId);
            sessionMap.remove(uuid);
        }
    }

    public static void sendMessage(String uuid, String message) {
        try {
            Session session = sessionMap.get(uuid);
            if (session != null) {
                session.getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            log.error("发送消息失败", e);
        }
    }

    @OnClose
    public void onClose(@PathParam("uuid") String uuid) {
        sessionMap.remove(uuid);
        // 可以遍历并清理wxUserMap中对应的记录
        wxUserMap.entrySet().removeIf(entry -> entry.getValue().equals(uuid));
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误", error);
    }
}